<template>
  <div class="route-plan-container">
    <!-- 页面标题 -->
  <div class="page-header">
      <h1 class="page-title">
        <el-icon><MapLocation /></el-icon>
        智能路线规划
      </h1>
      <p class="page-subtitle">基于Dijkstra算法，为您规划最优旅游路线</p>
    </div>

    <el-row :gutter="20">
      <!-- 左侧：规划表单 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="8">
        <el-card class="form-card" shadow="hover">
          <template #header>
            <div class="card-header">
              <el-icon><Setting /></el-icon>
              <span>规划参数</span>
            </div>
          </template>

          <el-form 
            :model="form" 
            :label-width="isMobile ? 'auto' : '100px'" 
            :rules="rules" 
            ref="formRef" 
            :label-position="isMobile ? 'top' : 'right'"
          >
            <el-form-item label="起始景点" prop="start_attraction_id">
              <div class="attraction-select-wrapper">
                <el-icon class="select-icon"><Location /></el-icon>
                <el-select
                  v-model="form.start_attraction_id"
                  placeholder="请选择起始景点"
                  filterable
                  style="width: 100%"
                  size="large"
                  class="attraction-select"
                >
                  <el-option
                    v-for="attr in attractions"
                    :key="attr.id"
                    :label="attr.name"
                    :value="attr.id"
                  >
                    <div class="attraction-option">
                      <span class="option-name">{{ attr.name }}</span>
                      <el-tag :type="getCategoryType(attr.category)" size="small" class="option-tag">
                        {{ attr.category_display }}
                      </el-tag>
                    </div>
                  </el-option>
                </el-select>
              </div>
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                选择您要出发的景点作为路线起点
              </div>
            </el-form-item>

            <el-form-item label="必访景点（可选）" prop="must_visit">
              <div class="attraction-select-wrapper">
                <el-icon class="select-icon"><View /></el-icon>
                <el-select
                  v-model="form.must_visit"
                  placeholder="请选择必访景点（可多选）"
                  multiple
                  filterable
                  style="width: 100%"
                  size="large"
                  collapse-tags
                  collapse-tags-tooltip
                  class="attraction-select"
                >
                  <el-option
                    v-for="attr in filteredAttractions"
                    :key="attr.id"
                    :label="attr.name"
                    :value="attr.id"
                  >
                    <div class="attraction-option">
                      <span>{{ attr.name }}</span>
                      <el-tag :type="getCategoryType(attr.category)" size="small" style="margin-left: 8px;">
                        {{ attr.category_display }}
                      </el-tag>
                    </div>
                  </el-option>
                </el-select>
              </div>
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                选择您必须访问的景点，系统将确保这些景点包含在路线中
              </div>
            </el-form-item>

            <el-form-item label="预算（元）" prop="budget">
              <div class="budget-input-wrapper">
                <el-icon class="budget-icon"><Money /></el-icon>
                <el-input-number
                  v-model="form.budget"
                  :min="0"
                  :max="50000"
                  :step="100"
                  :precision="0"
                  style="width: 100%"
                  size="large"
                  controls-position="right"
                  class="budget-input"
                />
              </div>
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                建议预算范围：500-5000元
              </div>
            </el-form-item>

            <el-form-item label="规划策略" prop="priority">
              <el-radio-group v-model="form.priority" size="large" class="priority-group">
                <el-radio-button label="distance" class="priority-button">
                  <el-icon><Location /></el-icon>
                  <span>距离优先</span>
                </el-radio-button>
                <el-radio-button label="cost" class="priority-button">
                  <el-icon><Money /></el-icon>
                  <span>费用优先</span>
                </el-radio-button>
                <el-radio-button label="balanced" class="priority-button">
                  <el-icon><ScaleToOriginal /></el-icon>
                  <span>平衡模式</span>
                </el-radio-button>
              </el-radio-group>
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                选择规划策略：距离优先（最短路线）、费用优先（最省费用）、平衡模式（综合考虑）
              </div>
            </el-form-item>

            <el-form-item label="交通方式" prop="transport_mode">
              <el-radio-group v-model="form.transport_mode" size="large" class="transport-group">
                <el-radio-button label="driving" class="transport-button">
                  <el-icon><Van /></el-icon>
                  <span>自驾</span>
                </el-radio-button>
                <el-radio-button label="transit" class="transport-button">
                  <el-icon><Guide /></el-icon>
                  <span>公交</span>
                </el-radio-button>
                <el-radio-button label="bicycling" class="transport-button">
                  <el-icon><Bicycle /></el-icon>
                  <span>骑行</span>
                </el-radio-button>
                <el-radio-button label="walking" class="transport-button">
                  <el-icon><Promotion /></el-icon>
                  <span>步行</span>
                </el-radio-button>
              </el-radio-group>
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                选择交通方式会影响路线规划的距离、时间和费用
              </div>
            </el-form-item>

            <el-form-item label="时间约束（可选）">
              <div class="time-constraint-wrapper">
                <el-row :gutter="12">
                  <el-col :span="12">
                    <div class="time-input-group">
                      <el-icon class="time-icon"><Clock /></el-icon>
                      <el-time-picker
                        v-model="form.start_time"
                        placeholder="开始时间"
                        format="HH:mm"
                        value-format="HH:mm"
                        style="width: 100%"
                        size="large"
                        clearable
                        class="time-picker-input"
                      />
                    </div>
                    <div class="form-tip">设置出发时间</div>
                  </el-col>
                  <el-col :span="12">
                    <div class="time-input-group">
                      <el-icon class="time-icon"><Timer /></el-icon>
                      <el-input-number
                        v-model="form.max_total_time"
                        :min="0"
                        :max="1440"
                        :step="30"
                        :precision="0"
                        placeholder="最大总时间"
                        style="width: 100%"
                        size="large"
                        controls-position="right"
                        class="time-number-input"
                      />
                    </div>
                    <div class="form-tip">0表示不限制（分钟）</div>
                  </el-col>
                </el-row>
                <el-alert
                  v-if="form.start_time || form.max_total_time"
                  type="info"
                  :closable="false"
                  show-icon
                  style="margin-top: 12px;"
                >
                  <template #default>
                    <div class="time-constraint-info">
                      <p v-if="form.start_time" style="margin: 0 0 4px 0;">
                        <el-icon><Clock /></el-icon>
                        出发时间：{{ form.start_time }}
                      </p>
                      <p v-if="form.max_total_time" style="margin: 0;">
                        <el-icon><Timer /></el-icon>
                        最大总时间：{{ form.max_total_time }} 分钟（{{ Math.floor(form.max_total_time / 60) }}小时{{ form.max_total_time % 60 }}分钟）
                      </p>
                      <p style="margin: 4px 0 0 0; font-size: 12px; color: #909399;">
                        系统将验证景点开放时间并确保路线在时间窗口内完成
                      </p>
                    </div>
                  </template>
                </el-alert>
              </div>
            </el-form-item>

            <el-form-item>
              <el-button 
                type="primary" 
                @click="calculateRoute" 
                :loading="loading"
                size="large"
                style="width: 100%"
                class="plan-button"
              >
                <el-icon><Search /></el-icon>
                开始规划路线
              </el-button>
              <el-button @click="resetForm" size="large" style="width: 100%; margin-top: 10px;" class="reset-button">
                重置参数
              </el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>

      <!-- 右侧：规划结果 -->
      <el-col :xs="24" :sm="24" :md="12" :lg="16">
        <!-- 结果卡片 -->
        <el-card v-if="routeResult" class="result-card" shadow="hover">
          <template #header>
            <div class="card-header">
              <div>
                <el-icon><SuccessFilled /></el-icon>
                <span>规划结果</span>
              </div>
              <div v-if="isAuthenticated && routeResult.id" class="header-actions">
                <el-button
                  v-if="!routeResult.is_shared"
                  type="primary"
                  size="small"
                  :icon="Share"
                  @click="shareRoute"
                  :loading="sharing"
                >
                  分享路线
                </el-button>
                <el-button
                  v-else
                  type="info"
                  size="small"
                  :icon="Share"
                  @click="unshareRoute"
                  :loading="sharing"
                >
                  取消分享
                </el-button>
                <el-button
                  v-if="routeResult.share_code"
                  type="success"
                  size="small"
                  :icon="CopyDocument"
                  @click="copyShareLink"
                >
                  复制链接
                </el-button>
                <el-button
                  v-if="routeResult.share_code"
                  type="warning"
                  size="small"
                  :icon="Picture"
                  @click="openQRCodeDialog"
                >
                  二维码
                </el-button>
                <el-button
                  type="default"
                  size="small"
                  :icon="List"
                  @click="openCompareDialog"
                >
                  对比路线
                </el-button>
                <el-button
                  v-if="isEditMode"
                  type="info"
                  size="small"
                  :icon="Close"
                  @click="cancelEditing"
                >
                  取消编辑
                </el-button>
                <el-button
                  v-if="isEditMode"
                  type="success"
                  size="small"
                  :icon="CircleCheck"
                  @click="finishEditing"
                  :loading="loading"
                >
                  完成编辑
                </el-button>
                <el-button
                  type="warning"
                  size="small"
                  :icon="Edit"
                  @click="toggleEditMode"
                >
                  {{ isEditMode ? '编辑中' : '编辑路线' }}
                </el-button>
                <el-button
                  v-if="routeResult.id"
                  :type="routeResult.is_favorited ? 'warning' : 'default'"
                  size="small"
                  :icon="routeResult.is_favorited ? StarFilled : Star"
                  @click="toggleRouteFavorite"
                  :loading="favoritingRoute"
                >
                  {{ routeResult.is_favorited ? '已收藏' : '收藏路线' }}
                </el-button>
              </div>
            </div>
          </template>

          <!-- 时间冲突警告 -->
          <el-alert
            v-if="hasTimeConflicts"
            title="时间冲突警告"
            type="warning"
            :closable="false"
            show-icon
            style="margin-bottom: 20px;"
          >
            <template #default>
              <div>
                <p>检测到路线中存在时间冲突：部分景点的到达时间不在开放时间内。</p>
                <p style="margin-top: 5px; font-size: 12px; color: #909399;">
                  建议：调整开始时间或重新规划路线，确保所有景点在开放时间内可访问。
                </p>
              </div>
            </template>
          </el-alert>

          <!-- 结果摘要 -->
          <div class="result-summary">
            <div class="summary-header">
              <h3 class="summary-title">
                <el-icon><SuccessFilled /></el-icon>
                路线概览
              </h3>
              <el-tag type="success" size="large" effect="dark">
                规划成功
              </el-tag>
            </div>
            <el-row :gutter="16" class="summary-grid">
              <el-col :xs="12" :sm="12" :md="6" :lg="6">
                <div class="summary-item distance">
                  <div class="summary-icon-wrapper">
                    <div class="summary-icon distance">
                      <el-icon><Location /></el-icon>
                    </div>
                  </div>
                  <div class="summary-content">
                    <div class="summary-label">总距离</div>
                    <div class="summary-value">{{ routeResult.optimal_route?.total_distance?.toFixed(2) || routeResult.total_distance?.toFixed(2) || 0 }}</div>
                    <div class="summary-unit">公里</div>
                  </div>
                </div>
              </el-col>
              <el-col :xs="12" :sm="12" :md="6" :lg="6">
                <div class="summary-item cost">
                  <div class="summary-icon-wrapper">
                    <div class="summary-icon cost">
                      <el-icon><Money /></el-icon>
                    </div>
                  </div>
                  <div class="summary-content">
                    <div class="summary-label">总费用</div>
                    <div class="summary-value">¥{{ routeResult.optimal_route?.total_cost?.toFixed(2) || routeResult.total_cost?.toFixed(2) || 0 }}</div>
                    <div class="summary-unit">元</div>
                  </div>
                </div>
              </el-col>
              <el-col :xs="12" :sm="12" :md="6" :lg="6">
                <div class="summary-item time">
                  <div class="summary-icon-wrapper">
                    <div class="summary-icon time">
                      <el-icon><Clock /></el-icon>
                    </div>
                  </div>
                  <div class="summary-content">
                    <div class="summary-label">总时间</div>
                    <div class="summary-value">{{ formatTime(routeResult.optimal_route?.total_time || routeResult.total_time || 0) }}</div>
                    <div class="summary-unit">小时</div>
                  </div>
                </div>
              </el-col>
              <el-col :xs="12" :sm="12" :md="6" :lg="6">
                <div class="summary-item time">
                  <div class="summary-icon-wrapper">
                    <div class="summary-icon time">
                      <el-icon><Clock /></el-icon>
                    </div>
                  </div>
                  <div class="summary-content">
                    <div class="summary-label">累计等待</div>
                    <div class="summary-value">{{ routeResult.optimal_route?.total_wait_time || routeResult.total_wait_time || 0 }}</div>
                    <div class="summary-unit">分钟</div>
                  </div>
                </div>
              </el-col>
              <el-col :xs="12" :sm="12" :md="6" :lg="6">
                <div class="summary-item count">
                  <div class="summary-icon-wrapper">
                    <div class="summary-icon count">
                      <el-icon><View /></el-icon>
                    </div>
                  </div>
                  <div class="summary-content">
                    <div class="summary-label">景点数量</div>
                    <div class="summary-value">{{ displayRouteDetails.length }}</div>
                    <div class="summary-unit">个</div>
                  </div>
                </div>
              </el-col>
            </el-row>
            
            <!-- 路线统计图表 -->
            <div v-if="routeResult.optimal_route || routeResult.total_cost" class="route-stats-chart">
              <div class="chart-header">
                <h4>费用分布</h4>
              </div>
              <div class="stats-bars">
                <div class="stat-bar-item">
                  <div class="bar-label">门票费用</div>
                  <div class="bar-container">
                    <div 
                      class="bar-fill ticket" 
                      :style="{ width: getTicketCostPercentage() + '%' }"
                    >
                      <span class="bar-value">¥{{ getTicketCost().toFixed(2) }}</span>
                    </div>
                  </div>
                </div>
                <div class="stat-bar-item">
                  <div class="bar-label">交通费用</div>
                  <div class="bar-container">
                    <div 
                      class="bar-fill transport" 
                      :style="{ width: getTransportCostPercentage() + '%' }"
                    >
                      <span class="bar-value">¥{{ getTransportCost().toFixed(2) }}</span>
                    </div>
                  </div>
                </div>
              </div>
              
              <div class="route-efficiency">
                <div class="efficiency-item">
                  <el-icon><Promotion /></el-icon>
                  <span>平均每景点费用：¥{{ getAverageCostPerAttraction().toFixed(2) }}</span>
                </div>
                <div class="efficiency-item">
                  <el-icon><Location /></el-icon>
                  <span>平均每景点距离：{{ getAverageDistancePerAttraction().toFixed(2) }} 公里</span>
                </div>
                <div class="efficiency-item">
                  <el-icon><Clock /></el-icon>
                  <span>平均每景点时间：{{ getAverageTimePerAttraction() }} 分钟</span>
                </div>
              </div>
            </div>
          </div>

          <!-- 路线详情 -->
          <div class="route-details">
            <div class="section-header">
              <div class="section-title-wrapper">
                <h3 class="section-title">
                  <el-icon><List /></el-icon>
                  路线详情
                </h3>
                <div class="route-badge">
                  <el-tag type="info" size="small">
                    {{ displayRouteDetails.length }} 个景点
                  </el-tag>
                  <el-tag v-if="routeResult.optimal_route?.total_distance" type="success" size="small">
                    {{ routeResult.optimal_route.total_distance.toFixed(2) }} 公里
                  </el-tag>
                </div>
              </div>
              <div v-if="isEditMode" class="edit-mode-tips">
                <el-alert
                  title="编辑模式"
                  type="warning"
                  :closable="false"
                  show-icon
                >
                  <template #default>
                    <div class="edit-tips-content">
                      <p>您可以调整景点顺序或删除景点，完成后点击"完成编辑"重新计算路线</p>
                      <div class="edit-tips-actions">
                        <el-button size="small" type="success" :icon="CircleCheck" @click="finishEditing" :loading="loading">
                          完成编辑
                        </el-button>
                        <el-button size="small" type="info" :icon="Close" @click="cancelEditing">
                          取消编辑
                        </el-button>
                      </div>
                    </div>
                  </template>
                </el-alert>
              </div>
            </div>
            <el-timeline>
              <el-timeline-item
                v-for="(detail, index) in displayRouteDetails"
                :key="`${detail.attraction_id || detail.attraction_name}-${index}`"
                :timestamp="`第${index + 1}站`"
                placement="top"
                :type="index === 0 ? 'primary' : 'success'"
                :icon="index === 0 ? 'Location' : 'CircleCheck'"
              >
                <el-card 
                  class="detail-card" 
                  :class="{ 'editable': isEditMode, 'is-start': index === 0 }"
                  shadow="hover"
                >
                  <div class="detail-header">
                    <div class="attraction-header-left">
                      <div class="attraction-order">
                        <div class="order-number">{{ index + 1 }}</div>
                        <div class="order-label">{{ index === 0 ? '起点' : '途经' }}</div>
                      </div>
                      <h4 class="attraction-name">{{ detail.attraction_name }}</h4>
                    </div>
                    <div class="header-actions">
                      <div v-if="isEditMode" class="edit-actions">
                        <el-button
                          v-if="index > 0"
                          type="primary"
                          size="small"
                          text
                          :icon="ArrowUp"
                          @click="moveAttractionUp(index)"
                          title="上移"
                          circle
                        />
                        <el-button
                          v-if="index < editableRouteDetails.length - 1"
                          type="primary"
                          size="small"
                          text
                          :icon="ArrowDown"
                          @click="moveAttractionDown(index)"
                          title="下移"
                          circle
                        />
                        <el-button
                          v-if="editableRouteDetails.length > 1"
                          type="danger"
                          size="small"
                          text
                          :icon="Delete"
                          @click="removeAttraction(index)"
                          title="删除"
                          circle
                        />
                      </div>
                    </div>
                  </div>
                  <el-descriptions :column="2" size="small" border>
                    <el-descriptions-item label="门票价格">
                      <span class="price-text">¥{{ detail.ticket_price }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item label="建议游览时间">
                      {{ detail.visit_time || 60 }} 分钟
                    </el-descriptions-item>
                    <el-descriptions-item v-if="detail.arrival_time" label="到达时间">
                      <el-tag type="success" size="small">{{ detail.arrival_time }}</el-tag>
                    </el-descriptions-item>
                    <el-descriptions-item v-if="detail.wait_time && detail.wait_time > 0" label="等待开门">
                      <el-tag type="warning" size="small">{{ detail.wait_time }} 分钟</el-tag>
                      <span v-if="detail.arrival_before_wait" style="margin-left: 8px; color: #909399;">原始到达：{{ detail.arrival_before_wait }}</span>
                    </el-descriptions-item>
                    <el-descriptions-item v-if="detail.departure_time" label="离开时间">
                      <el-tag type="info" size="small">{{ detail.departure_time }}</el-tag>
                    </el-descriptions-item>
                    <el-descriptions-item v-if="detail.open_time && detail.close_time" label="开放时间" :span="2">
                      {{ detail.open_time }} - {{ detail.close_time }}
                      <el-tag 
                        v-if="checkTimeConflict(detail)" 
                        type="danger" 
                        size="small" 
                        style="margin-left: 10px;"
                      >
                        时间冲突
                      </el-tag>
                    </el-descriptions-item>
                  </el-descriptions>
                  <div v-if="detail.from_previous" class="route-info">
                    <el-divider />
                    <div class="transport-info">
                      <el-icon><Right /></el-icon>
                      <span>从上一站到达</span>
                    </div>
                    <el-descriptions :column="3" size="small" border>
                      <el-descriptions-item label="距离">
                        {{ detail.from_previous.distance }} 公里
                      </el-descriptions-item>
                      <el-descriptions-item label="交通费用">
                        ¥{{ detail.from_previous.cost }}
                      </el-descriptions-item>
                      <el-descriptions-item label="交通时间">
                        {{ detail.from_previous.time }} 分钟
                      </el-descriptions-item>
                    </el-descriptions>
                  </div>
                </el-card>
              </el-timeline-item>
            </el-timeline>
          </div>

          <!-- 路线地图 -->
          <div class="map-container">
            <div class="map-header">
              <h3 class="section-title">
                <el-icon><MapLocation /></el-icon>
                路线地图
              </h3>
              <div class="map-controls">
                <el-tooltip content="适应视野" placement="top">
                  <el-button 
                    size="small" 
                    :icon="FullScreen" 
                    circle
                    @click="fitMapView"
                    class="map-control-btn"
                  />
                </el-tooltip>
                <el-tooltip content="刷新地图" placement="top">
                  <el-button 
                    size="small" 
                    :icon="RefreshRight" 
                    circle
                    @click="refreshMap"
                    class="map-control-btn"
                  />
                </el-tooltip>
                <el-tooltip content="切换地图样式" placement="top">
                  <el-button 
                    size="small" 
                    :icon="Switch" 
                    circle
                    @click="toggleMapStyle"
                    class="map-control-btn"
                  />
                </el-tooltip>
              </div>
            </div>
            <div id="route-map" class="route-map" v-loading="mapLoading"></div>
            <div class="map-legend">
              <div class="legend-item">
                <span class="legend-marker start"></span>
                <span>起点</span>
              </div>
              <div class="legend-item">
                <span class="legend-marker waypoint"></span>
                <span>途经点</span>
              </div>
              <div class="legend-item">
                <span class="legend-marker route"></span>
                <span>路线</span>
              </div>
            </div>
          </div>
        </el-card>

        <!-- 空状态 -->
        <el-card v-else class="empty-card" shadow="hover">
          <el-empty description="请填写规划参数，开始规划您的旅游路线">
            <el-icon class="empty-icon"><MapLocation /></el-icon>
          </el-empty>
        </el-card>
      </el-col>
    </el-row>

    <!-- 路线对比对话框 -->
    <el-dialog
      v-model="showCompareDialog"
      title="路线对比"
      width="1200px"
      :close-on-click-modal="false"
    >
      <div v-if="savedRoutes.length > 0">
        <el-alert
          type="info"
          :closable="false"
          style="margin-bottom: 20px;"
        >
          <template #default>
            <span>选择要对比的路线（最多3条），当前路线已自动选中</span>
          </template>
        </el-alert>
        
        <el-table
          :data="savedRoutes"
          @selection-change="handleRouteSelectionChange"
          ref="compareTableRef"
          style="margin-bottom: 20px;"
        >
          <el-table-column type="selection" width="55" :selectable="checkSelectable" />
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column label="预算" width="100">
            <template #default="scope">
              ¥{{ scope.row.budget }}
            </template>
          </el-table-column>
          <el-table-column label="总费用" width="100">
            <template #default="scope">
              ¥{{ scope.row.total_cost || 'N/A' }}
            </template>
          </el-table-column>
          <el-table-column label="总距离" width="100">
            <template #default="scope">
              {{ scope.row.total_distance || 'N/A' }} 公里
            </template>
          </el-table-column>
          <el-table-column label="景点数" width="100">
            <template #default="scope">
              {{ scope.row.optimal_route?.route?.length || 0 }} 个
            </template>
          </el-table-column>
          <el-table-column prop="created_at" label="创建时间" width="180" />
        </el-table>
        
        <div v-if="selectedRoutesForCompare.length > 0" class="compare-results">
          <h3 style="margin-bottom: 20px;">对比结果</h3>
          <el-table :data="compareTableData" border stripe>
            <el-table-column prop="metric" label="对比项" width="150" fixed="left" />
            <el-table-column
              v-for="(route, index) in selectedRoutesForCompare"
              :key="route.id"
              :label="`路线 ${index + 1}`"
              :prop="`route${index + 1}`"
            >
              <template #default="scope">
                <span :class="getCompareCellClass(scope.row.metric, scope.row[`route${index + 1}`], scope.row)">
                  {{ scope.row[`route${index + 1}`] }}
                </span>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <el-empty v-else description="请选择至少一条路线进行对比" />
      </div>
      <el-empty v-else description="暂无保存的路线，请先保存一些路线后再进行对比" />
      
      <template #footer>
        <el-button @click="showCompareDialog = false">关闭</el-button>
        <el-button
          type="primary"
          @click="loadSavedRoutes"
          :loading="loading"
        >
          刷新列表
        </el-button>
      </template>
    </el-dialog>

    <!-- 二维码对话框 -->
    <el-dialog
      v-model="showQRCodeDialog"
      title="分享二维码"
      width="400px"
      center
    >
      <div style="text-align: center; padding: 20px;">
        <div v-if="shareQRCodeUrl" style="margin-bottom: 20px;">
          <img :src="shareQRCodeUrl" alt="分享二维码" style="max-width: 100%; border: 1px solid #ddd; border-radius: 8px;" />
        </div>
        <div v-else style="padding: 40px;">
          <el-icon class="is-loading" style="font-size: 40px;"><Loading /></el-icon>
          <p style="margin-top: 10px; color: #909399;">正在生成二维码...</p>
        </div>
        <div v-if="shareUrl" style="margin-top: 20px;">
          <el-input
            :model-value="shareUrl"
            readonly
            style="margin-bottom: 10px;"
          >
            <template #append>
              <el-button :icon="CopyDocument" @click="copyShareLinkFromDialog">复制</el-button>
            </template>
          </el-input>
        </div>
      </div>
    </el-dialog>
  </div>

    <!-- 异步规划进度对话框 -->
    <el-dialog
      v-model="planningAsync"
      title="正在规划路线"
      :close-on-click-modal="false"
      :show-close="false"
      width="420px"
    >
      <div class="planning-status">
        <el-icon><Clock /></el-icon>
        <span class="planning-text">{{ progressMessage }}</span>
      </div>
      <template #footer>
        <el-button @click="cancelAsyncPlanning">取消</el-button>
      </template>
    </el-dialog>
</template>

<script>
import { ref, reactive, onMounted, onUnmounted, computed, nextTick } from 'vue'
import { useStore } from 'vuex'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Share,
  CopyDocument,
  MapLocation,
  Setting,
  Search,
  Location,
  Money,
  ScaleToOriginal,
  SuccessFilled,
  View,
  List,
  Right,
  CircleCheck,
  Van,
  Guide,
  Bicycle,
  Promotion,
  Clock,
  Timer,
  Edit,
  Delete,
  ArrowUp,
  ArrowDown,
  Close,
  Picture,
  Loading,
  Star,
  StarFilled,
  InfoFilled,
  FullScreen,
  RefreshRight,
  Switch
} from '@element-plus/icons-vue'
import TravelAPI from '../api/travel'
import { AMapUtil } from '../utils/amap'
import logger from '../utils/logger'
import { useResponsive } from '../utils/responsive'

export default {
  name: 'RoutePlan',
  setup() {
    const store = useStore()
    const formRef = ref(null)
    const loading = ref(false)
    const planningAsync = ref(false)
    const progressMessage = ref('')
    const isPollingCancelled = ref(false)
    const attractions = ref([])
    const routeResult = ref(null)
    const amapUtil = ref(null)
    const sharing = ref(false)
    const showQRCodeDialog = ref(false)
    const mapLoading = ref(false)
    const mapStyleIndex = ref(0)
    const isEditMode = ref(false)
    const editableRouteDetails = ref([])
    const originalRouteDetails = ref([]) // 保存原始路线，用于取消编辑
    const shareQRCodeUrl = ref('')
    const shareUrl = ref('')
    const savedRoutes = ref([])  // 保存的路线历史
    const showCompareDialog = ref(false)  // 路线对比对话框
    const selectedRoutesForCompare = ref([])  // 选中的对比路线
    const compareTableRef = ref(null)  // 对比表格引用
    const favoritingRoute = ref(false)  // 路线收藏加载状态
    
    const isAuthenticated = computed(() => store.getters.isAuthenticated)
    
    // 使用响应式工具
    const responsive = useResponsive()
    const isMobile = computed(() => responsive.isMobile.value)
    const isTablet = computed(() => responsive.isTablet.value)
    const isDesktop = computed(() => responsive.isDesktop.value)
    const deviceType = computed(() => responsive.deviceType.value)

    const form = reactive({
      start_attraction_id: null,
      must_visit: [],
      budget: 1000,
      priority: 'balanced',
      transport_mode: 'driving',
      start_time: null,  // 开始时间（HH:mm格式）
      max_total_time: null  // 最大总时间（分钟）
    })

    const rules = {
      start_attraction_id: [
        { required: true, message: '请选择起始景点', trigger: 'change' }
      ],
      budget: [
        { required: true, message: '请输入预算', trigger: 'blur' },
        { type: 'number', min: 0, message: '预算必须大于等于0', trigger: 'blur' },
        { type: 'number', max: 50000, message: '预算不能超过50000元', trigger: 'blur' },
        {
          validator: (rule, value, callback) => {
            if (value && value < 100) {
              callback(new Error('预算过小，建议至少100元'))
            } else {
              callback()
            }
          },
          trigger: 'blur'
        }
      ],
      must_visit: [
        {
          validator: (rule, value, callback) => {
            if (value && value.length > 0 && form.start_attraction_id && value.includes(form.start_attraction_id)) {
              callback(new Error('必访景点不能包含起始景点'))
            } else {
              callback()
            }
          },
          trigger: 'change'
        }
      ],
      max_total_time: [
        {
          validator: (rule, value, callback) => {
            if (value && value < 30) {
              callback(new Error('最大总时间至少需要30分钟'))
            } else if (value && value > 1440) {
              callback(new Error('最大总时间不能超过24小时（1440分钟）'))
            } else {
              callback()
            }
          },
          trigger: 'blur'
        }
      ]
    }

    const filteredAttractions = computed(() => {
      return attractions.value.filter(attr => attr.id !== form.start_attraction_id)
    })

    const getCategoryType = (category) => {
      const types = {
        'cultural': 'warning',
        'natural': 'success',
        'modern': 'info',
        'food': 'danger'
      }
      return types[category] || 'info'
    }

    // 获取景点列表（使用缓存优化）
    const fetchAttractionsImmediate = async () => {
      try {
        const data = await TravelAPI.getAttractions()
        attractions.value = Array.isArray(data) ? data : data.results || []
        if (attractions.value.length === 0) {
          ElMessage.warning('暂无景点数据')
        }
      } catch (error) {
        import('../utils/errorHandler').then(({ handleApiError }) => {
          handleApiError(error, { defaultMessage: '获取景点列表失败' })
        })
      }
    }

    const calculateRoute = async () => {
      if (!formRef.value) return

      try {
        // 表单验证
        await formRef.value.validate()
        
        // 额外验证：检查必访景点是否包含起始景点
        if (form.must_visit && form.must_visit.length > 0 && form.start_attraction_id) {
          if (form.must_visit.includes(form.start_attraction_id)) {
            ElMessage.warning('必访景点不能包含起始景点')
            return
          }
        }
        
        // 验证预算范围
        if (form.budget <= 0) {
          ElMessage.warning('预算必须大于0')
          return
        }
        if (form.budget > 10000) {
          ElMessage.warning('预算不能超过10000元')
          return
        }
        
        // 验证最大总时间
        if (form.max_total_time && form.max_total_time > 0) {
          if (form.max_total_time < 30) {
            ElMessage.warning('最大总时间不能少于30分钟')
            return
          }
          if (form.max_total_time > 1440) {
            ElMessage.warning('最大总时间不能超过1440分钟（24小时）')
            return
          }
        }
        
        loading.value = true

        const params = {
          start_attraction_id: form.start_attraction_id,
          must_visit: form.must_visit,
          budget: form.budget,
          priority: form.priority,
          transport_mode: form.transport_mode
        }
        
        // 添加时间约束参数
        if (form.start_time) {
          params.start_time = form.start_time
        }
        if (form.max_total_time && form.max_total_time > 0) {
          params.max_total_time = form.max_total_time
        }

        // 当必访景点数量较多时，使用异步规划以避免阻塞
        let result
        if (Array.isArray(params.must_visit) && params.must_visit.length > 10) {
          planningAsync.value = true
          isPollingCancelled.value = false
          progressMessage.value = '正在计算最优路线...'
          const task = await TravelAPI.planRouteAsync(params)
          const taskId = task?.task_id
          if (!taskId) {
            ElMessage.error('异步规划任务创建失败')
            loading.value = false
            planningAsync.value = false
            return
          }
          // 轮询任务状态
          result = await pollPlanStatus(taskId)
          planningAsync.value = false
        } else {
          result = await TravelAPI.planRoute(params)
        }
        routeResult.value = result
        
        // 初始化可编辑路线详情
        if (result.optimal_route && result.optimal_route.details) {
          editableRouteDetails.value = [...result.optimal_route.details]
          originalRouteDetails.value = [...result.optimal_route.details]
        }
        
        // 如果结果有ID，说明已保存，获取完整信息（包括分享状态和收藏状态）
        if (result.id) {
          try {
            const historyData = await TravelAPI.getRouteHistory({ page_size: 50 })
            const historyList = historyData.results || historyData || []
            const savedRoute = historyList.find(r => r.id === result.id)
            if (savedRoute) {
              routeResult.value = { ...routeResult.value, ...savedRoute }
              // 更新可编辑路线详情
              if (savedRoute.optimal_route && savedRoute.optimal_route.details) {
                editableRouteDetails.value = [...savedRoute.optimal_route.details]
                originalRouteDetails.value = [...savedRoute.optimal_route.details]
              }
            } else {
              // 如果历史记录中没有，尝试从API获取详情（包含收藏状态）
              // 注意：这里需要确保API返回收藏状态
              routeResult.value.is_favorited = routeResult.value.is_favorited || false
            }
          } catch (error) {
            // 获取路线详情失败不影响主流程，只记录错误
            logger.error('获取路线详情失败:', error)
            // 设置默认值
            routeResult.value.is_favorited = routeResult.value.is_favorited || false
          }
        }

        // 绘制地图
        if (result.optimal_route && result.optimal_route.details) {
          await drawRouteMap(result.optimal_route.details)
        }
        
        // 退出编辑模式（如果有）
        isEditMode.value = false

        ElMessage.success('路线规划成功')
      } catch (error) {
        logger.error('路线规划失败:', error)
        
        // 更详细的错误处理
        let errorMessage = '路线规划失败'
        if (error.response) {
          const status = error.response.status
          const data = error.response.data
          
          if (status === 400) {
            errorMessage = data?.error || data?.detail || '请求参数错误，请检查输入信息'
          } else if (status === 401) {
            errorMessage = '登录已过期，请重新登录'
          } else if (status === 403) {
            errorMessage = '没有权限执行此操作'
          } else if (status === 404) {
            errorMessage = '未找到相关资源'
          } else if (status === 500) {
            errorMessage = '服务器错误，请稍后重试'
          } else if (data?.error) {
            errorMessage = data.error
          } else if (data?.detail) {
            errorMessage = data.detail
          }
        } else if (error.message) {
          if (error.message.includes('timeout')) {
            errorMessage = '请求超时，请检查网络连接后重试'
          } else if (error.message.includes('Network Error')) {
            errorMessage = '网络错误，请检查网络连接'
          } else {
            errorMessage = error.message
          }
        }
        
        ElMessage.error(errorMessage)
      } finally {
        loading.value = false
      }
    }

    const drawRouteMap = async (details) => {
      mapLoading.value = true
      try {
        // 获取API Key
        const apiKey = process.env.VUE_APP_AMAP_KEY || ''
        if (!apiKey || apiKey === 'your_amap_api_key') {
          ElMessage.warning('高德地图API Key未配置，地图功能不可用')
          return
        }

        // 等待地图容器渲染
        await new Promise(resolve => setTimeout(resolve, 500))

        if (!amapUtil.value) {
          amapUtil.value = new AMapUtil(apiKey)
        }

        // 清除之前的地图实例
        if (amapUtil.value.map) {
          amapUtil.value.map.destroy()
          amapUtil.value.map = null
        }

        // 计算中心点（所有景点的平均位置）
        const centerLng = details.reduce((sum, d) => sum + parseFloat(d.longitude), 0) / details.length
        const centerLat = details.reduce((sum, d) => sum + parseFloat(d.latitude), 0) / details.length

        await amapUtil.value.initMap('route-map', {
          center: [centerLng, centerLat],
          zoom: 12
        })

        // 应用地图样式
        applyMapStyle()

        // 准备标记点数据（区分起点和途经点）
        const markers = details.map((detail, index) => {
          const isStart = index === 0
          return {
            lng: parseFloat(detail.longitude),
            lat: parseFloat(detail.latitude),
            title: `${index + 1}. ${detail.attraction_name}`,
            isStart: isStart,
            index: index,
            info: `
              <div style="padding: 12px; min-width: 220px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;">
                <h3 style="margin: 0 0 12px 0; color: #409eff; font-size: 16px; font-weight: 600; border-bottom: 2px solid #409eff; padding-bottom: 8px;">
                  ${index + 1}. ${detail.attraction_name}
                </h3>
                <div style="margin: 8px 0;">
                  <span style="color: #909399; font-size: 13px;">门票：</span>
                  <span style="color: #C8102E; font-weight: 600; font-size: 15px;">¥${detail.ticket_price}</span>
                </div>
                ${detail.visit_time ? `
                  <div style="margin: 8px 0;">
                    <span style="color: #909399; font-size: 13px;">游览时间：</span>
                    <span style="color: #606266; font-size: 13px;">${detail.visit_time}分钟</span>
                  </div>
                ` : ''}
                ${detail.from_previous ? `
                  <div style="margin: 8px 0; padding: 6px; background: #f0f9ff; border-radius: 4px; border-left: 3px solid #67c23a;">
                    <span style="color: #67c23a; font-size: 13px; font-weight: 500;">距离上一站：${detail.from_previous.distance}公里</span>
                    ${detail.from_previous.cost ? `<span style="color: #909399; font-size: 12px; margin-left: 8px;">费用：¥${detail.from_previous.cost}</span>` : ''}
                  </div>
                ` : ''}
              </div>
            `
          }
        })

        // 准备路线数据
        const path = details.map(detail => [parseFloat(detail.longitude), parseFloat(detail.latitude)])

        amapUtil.value.addMarkers(markers)
        amapUtil.value.drawRoute(path)
      } catch (error) {
        logger.error('地图绘制失败:', error)
        ElMessage.error('地图加载失败: ' + (error.message || '未知错误'))
      } finally {
        mapLoading.value = false
      }
    }

    // 适应视野
    const fitMapView = () => {
      if (!amapUtil.value || !amapUtil.value.map) {
        ElMessage.warning('地图未加载')
        return
      }
      if (amapUtil.value.markers && amapUtil.value.markers.length > 0) {
        amapUtil.value.map.setFitView(amapUtil.value.markers, false, [50, 50, 50, 50])
        ElMessage.success('已适应视野')
      }
    }

    // 刷新地图
    const refreshMap = () => {
      if (!routeResult.value?.optimal_route?.details) {
        ElMessage.warning('没有可显示的地图数据')
        return
      }
      drawRouteMap(routeResult.value.optimal_route.details)
      ElMessage.success('地图已刷新')
    }

    // 切换地图样式
    const mapStyles = [
      'normal', // 标准
      'dark',   // 幻影黑
      'light',  // 月光银
      'fresh',  // 草色青青
      'grey',   // 雅士灰
      'graffiti', // 涂鸦
      'macaron',  // 马卡龙
      'blue',     // 靛青蓝
      'darkblue', // 极夜蓝
      'wine'      // 酱籽
    ]

    const applyMapStyle = () => {
      if (!amapUtil.value || !amapUtil.value.map) return
      
      const styleName = mapStyles[mapStyleIndex.value]
      if (styleName === 'normal') {
        amapUtil.value.map.setMapStyle('amap://styles/normal')
      } else {
        amapUtil.value.map.setMapStyle(`amap://styles/${styleName}`)
      }
    }

    const toggleMapStyle = () => {
      mapStyleIndex.value = (mapStyleIndex.value + 1) % mapStyles.length
      applyMapStyle()
      const styleNames = {
        'normal': '标准',
        'dark': '幻影黑',
        'light': '月光银',
        'fresh': '草色青青',
        'grey': '雅士灰',
        'graffiti': '涂鸦',
        'macaron': '马卡龙',
        'blue': '靛青蓝',
        'darkblue': '极夜蓝',
        'wine': '酱籽'
      }
      ElMessage.success(`地图样式已切换为：${styleNames[mapStyles[mapStyleIndex.value]]}`)
    }

    const resetForm = () => {
      if (formRef.value) {
        formRef.value.resetFields()
      }
      // 重置表单值
      form.start_attraction_id = null
      form.must_visit = []
      form.budget = 1000
      form.priority = 'balanced'
      form.transport_mode = 'driving'
      form.start_time = null
      form.max_total_time = null
      routeResult.value = null
      if (amapUtil.value) {
        amapUtil.value.clearMarkers()
        amapUtil.value.clearRoute()
      }
    }

    const shareRoute = async () => {
      if (!routeResult.value?.id) {
        ElMessage.warning('请先规划路线')
        return
      }

      sharing.value = true
      try {
        const response = await TravelAPI.shareRoute(routeResult.value.id)
        routeResult.value.is_shared = true
        routeResult.value.share_code = response.share_code
        ElMessage.success('分享成功！分享链接已生成')
      } catch (error) {
        logger.error('分享失败:', error)
        let errorMessage = '分享失败'
        if (error.response?.data?.error) {
          errorMessage = error.response.data.error
        } else if (error.response?.data?.detail) {
          errorMessage = error.response.data.detail
        } else if (error.message) {
          errorMessage = error.message
        }
        ElMessage.error(errorMessage)
      } finally {
        sharing.value = false
      }
    }

    const unshareRoute = async () => {
      if (!routeResult.value?.id) {
        return
      }

      sharing.value = true
      try {
        await TravelAPI.unshareRoute(routeResult.value.id)
        routeResult.value.is_shared = false
        routeResult.value.share_code = null
        ElMessage.success('已取消分享')
      } catch (error) {
        logger.error('取消分享失败:', error)
        let errorMessage = '取消分享失败'
        if (error.response?.data?.error) {
          errorMessage = error.response.data.error
        } else if (error.response?.data?.detail) {
          errorMessage = error.response.data.detail
        } else if (error.message) {
          errorMessage = error.message
        }
        ElMessage.error(errorMessage)
      } finally {
        sharing.value = false
      }
    }

    const copyShareLink = () => {
      if (!routeResult.value?.share_code) {
        ElMessage.warning('分享码不存在')
        return
      }

      const url = `${window.location.origin}/route-share/${routeResult.value.share_code}`
      
      // 优先使用现代 Clipboard API
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(url).then(() => {
          ElMessage.success('分享链接已复制到剪贴板')
        }).catch(() => {
          // 降级方案：使用传统方法
          fallbackCopyToClipboard(url)
        })
      } else {
        // 降级方案：使用传统方法
        fallbackCopyToClipboard(url)
      }
    }

    const generateQRCode = (url) => {
      // 使用在线API生成二维码（无需安装额外依赖）
      // 使用 qr-server.com 的免费API
      const encodedUrl = encodeURIComponent(url)
      return `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodedUrl}`
    }

    const openQRCodeDialog = () => {
      if (!routeResult.value?.share_code) {
        ElMessage.warning('分享码不存在，请先分享路线')
        return
      }

      shareUrl.value = `${window.location.origin}/route-share/${routeResult.value.share_code}`
      shareQRCodeUrl.value = generateQRCode(shareUrl.value)
      showQRCodeDialog.value = true
    }

    const copyShareLinkFromDialog = () => {
      if (!shareUrl.value) return
      
      // 优先使用现代 Clipboard API
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(shareUrl.value).then(() => {
          ElMessage.success('分享链接已复制到剪贴板')
        }).catch(() => {
          fallbackCopyToClipboard(shareUrl.value)
        })
      } else {
        fallbackCopyToClipboard(shareUrl.value)
      }
    }

    const fallbackCopyToClipboard = (text) => {
      try {
        const textArea = document.createElement('textarea')
        textArea.value = text
        textArea.style.position = 'fixed'
        textArea.style.left = '-999999px'
        textArea.style.top = '-999999px'
        document.body.appendChild(textArea)
        textArea.focus()
        textArea.select()
        const successful = document.execCommand('copy')
        document.body.removeChild(textArea)
        
        if (successful) {
          ElMessage.success('分享链接已复制到剪贴板')
        } else {
          ElMessage.info('请手动复制链接: ' + text)
        }
      } catch (error) {
        logger.error('复制失败:', error)
        ElMessage.info('请手动复制链接: ' + text)
      }
    }

    const formatTime = (minutes) => {
      if (!minutes || minutes <= 0) return '0分钟'
      const hours = Math.floor(minutes / 60)
      const mins = minutes % 60
      if (hours > 0 && mins > 0) {
        return `${hours}小时${mins}分钟`
      } else if (hours > 0) {
        return `${hours}小时`
      } else {
        return `${mins}分钟`
      }
    }

    // 计算门票费用
    const getTicketCost = () => {
      if (!routeResult.value || !displayRouteDetails.value.length) return 0
      return displayRouteDetails.value.reduce((sum, detail) => sum + (parseFloat(detail.ticket_price) || 0), 0)
    }

    // 计算交通费用
    const getTransportCost = () => {
      if (!routeResult.value || !displayRouteDetails.value.length) return 0
      const totalCost = parseFloat(routeResult.value.optimal_route?.total_cost || routeResult.value.total_cost || 0)
      return Math.max(0, totalCost - getTicketCost())
    }

    // 计算门票费用百分比
    const getTicketCostPercentage = () => {
      const totalCost = parseFloat(routeResult.value?.optimal_route?.total_cost || routeResult.value?.total_cost || 1)
      if (totalCost === 0) return 0
      return (getTicketCost() / totalCost) * 100
    }

    // 计算交通费用百分比
    const getTransportCostPercentage = () => {
      const totalCost = parseFloat(routeResult.value?.optimal_route?.total_cost || routeResult.value?.total_cost || 1)
      if (totalCost === 0) return 0
      return (getTransportCost() / totalCost) * 100
    }

    // 计算平均每景点费用
    const getAverageCostPerAttraction = () => {
      if (!displayRouteDetails.value.length) return 0
      const totalCost = parseFloat(routeResult.value?.optimal_route?.total_cost || routeResult.value?.total_cost || 0)
      return totalCost / displayRouteDetails.value.length
    }

    // 计算平均每景点距离
    const getAverageDistancePerAttraction = () => {
      if (!displayRouteDetails.value.length) return 0
      const totalDistance = parseFloat(routeResult.value?.optimal_route?.total_distance || routeResult.value?.total_distance || 0)
      return totalDistance / displayRouteDetails.value.length
    }

    // 计算平均每景点时间
    const getAverageTimePerAttraction = () => {
      if (!displayRouteDetails.value.length) return 0
      const totalTime = parseFloat(routeResult.value?.optimal_route?.total_time || routeResult.value?.total_time || 0)
      return Math.round(totalTime / displayRouteDetails.value.length)
    }

    const loadSavedRoutes = async () => {
      if (!isAuthenticated.value) {
        ElMessage.warning('请先登录以查看保存的路线')
        return
      }
      
      try {
        const historyData = await TravelAPI.getRouteHistory({ page_size: 50 })
        savedRoutes.value = historyData.results || historyData || []
      } catch (error) {
        logger.error('获取路线历史失败:', error)
        ElMessage.error('获取路线历史失败')
      }
    }
    
    const openCompareDialog = async () => {
      if (!isAuthenticated.value) {
        ElMessage.warning('请先登录以使用路线对比功能')
        return
      }
      
      showCompareDialog.value = true
      
      // 加载保存的路线
      if (savedRoutes.value.length === 0) {
        await loadSavedRoutes()
      }
      
      // 自动选中当前路线
      if (routeResult.value?.id) {
        selectedRoutesForCompare.value = [routeResult.value]
        // 等待DOM更新后设置表格选中状态
        await nextTick()
        if (compareTableRef.value) {
          const currentRoute = savedRoutes.value.find(r => r.id === routeResult.value.id)
          if (currentRoute) {
            compareTableRef.value.toggleRowSelection(currentRoute, true)
          }
        }
      }
    }
    
    const checkSelectable = (row) => {
      // 最多选择3条路线
      if (selectedRoutesForCompare.value.length >= 3) {
        return selectedRoutesForCompare.value.some(r => r.id === row.id)
      }
      return true
    }
    
    const handleRouteSelectionChange = (selection) => {
      // 限制最多选择3条
      if (selection.length > 3) {
        ElMessage.warning('最多只能选择3条路线进行对比')
        selectedRoutesForCompare.value = selection.slice(0, 3)
      } else {
        selectedRoutesForCompare.value = selection
      }
    }
    
    const compareTableData = computed(() => {
      if (selectedRoutesForCompare.value.length === 0) {
        return []
      }
      
      const routes = selectedRoutesForCompare.value
      const data = []
      
      // 预算对比
      data.push({
        metric: '预算',
        ...routes.reduce((acc, route, index) => {
          acc[`route${index + 1}`] = `¥${route.budget || 0}`
          return acc
        }, {})
      })
      
      // 总费用对比
      data.push({
        metric: '总费用',
        ...routes.reduce((acc, route, index) => {
          acc[`route${index + 1}`] = `¥${route.total_cost || 0}`
          return acc
        }, {})
      })
      
      // 总距离对比
      data.push({
        metric: '总距离',
        ...routes.reduce((acc, route, index) => {
          acc[`route${index + 1}`] = `${route.total_distance || 0} 公里`
          return acc
        }, {})
      })
      
      // 景点数量对比
      data.push({
        metric: '景点数量',
        ...routes.reduce((acc, route, index) => {
          acc[`route${index + 1}`] = `${route.optimal_route?.route?.length || 0} 个`
          return acc
        }, {})
      })
      
      // 总时间对比
      data.push({
        metric: '总时间',
        ...routes.reduce((acc, route, index) => {
          acc[`route${index + 1}`] = route.total_time ? formatTime(route.total_time) : '未设置'
          return acc
        }, {})
      })
      
      // 性价比（预算/景点数）
      data.push({
        metric: '性价比（预算/景点）',
        ...routes.reduce((acc, route, index) => {
          const attractionCount = route.optimal_route?.route?.length || 1
          const value = attractionCount > 0 ? (route.budget / attractionCount).toFixed(2) : 'N/A'
          acc[`route${index + 1}`] = value !== 'N/A' ? `¥${value}/景点` : 'N/A'
          return acc
        }, {})
      })
      
      // 平均每个景点费用
      data.push({
        metric: '平均景点费用',
        ...routes.reduce((acc, route, index) => {
          const attractionCount = route.optimal_route?.route?.length || 1
          const totalCost = route.total_cost || 0
          const value = attractionCount > 0 ? (totalCost / attractionCount).toFixed(2) : 'N/A'
          acc[`route${index + 1}`] = value !== 'N/A' ? `¥${value}/景点` : 'N/A'
          return acc
        }, {})
      })
      
      // 平均每个景点距离
      data.push({
        metric: '平均景点距离',
        ...routes.reduce((acc, route, index) => {
          const attractionCount = route.optimal_route?.route?.length || 1
          const totalDistance = route.total_distance || 0
          const value = attractionCount > 0 ? (totalDistance / attractionCount).toFixed(2) : 'N/A'
          acc[`route${index + 1}`] = value !== 'N/A' ? `${value} 公里/景点` : 'N/A'
          return acc
        }, {})
      })
      
      // 起始景点
      data.push({
        metric: '起始景点',
        ...routes.reduce((acc, route, index) => {
          acc[`route${index + 1}`] = route.start_attraction?.name || '未知'
          return acc
        }, {})
      })
      
      return data
    })
    
    const getCompareCellClass = (metric, value, row) => {
      // 对于费用和距离，值越小越好，标记为绿色
      if (metric === '总费用' || metric === '总距离') {
        const values = Object.keys(row)
          .filter(key => key.startsWith('route'))
          .map(key => {
            const val = row[key]
            if (typeof val === 'string') {
              const num = parseFloat(val.replace(/[^\d.]/g, ''))
              return isNaN(num) ? Infinity : num
            }
            return Infinity
          })
        const minValue = Math.min(...values)
        const currentValue = parseFloat(String(value).replace(/[^\d.]/g, ''))
        if (!isNaN(currentValue) && currentValue === minValue) {
          return 'best-value'
        }
      }
      return ''
    }
    
    const toggleRouteFavorite = async () => {
      if (!isAuthenticated.value) {
        ElMessage.warning('请先登录以收藏路线')
        return
      }
      
      if (!routeResult.value?.id) {
        ElMessage.warning('路线不存在')
        return
      }
      
      favoritingRoute.value = true
      try {
        const isFavorited = routeResult.value.is_favorited || false
        await TravelAPI.toggleRouteFavorite(routeResult.value.id, !isFavorited)
        
        // 更新收藏状态
        routeResult.value.is_favorited = !isFavorited
        ElMessage.success(isFavorited ? '已取消收藏' : '收藏成功')
      } catch (error) {
        logger.error('路线收藏操作失败:', error)
        let errorMessage = '操作失败'
        if (error.response) {
          const status = error.response.status
          if (status === 401) {
            errorMessage = '登录已过期，请重新登录'
          } else if (status === 403) {
            errorMessage = '没有权限执行此操作'
          } else if (error.response.data?.error) {
            errorMessage = error.response.data.error
          } else if (error.response.data?.detail) {
            errorMessage = error.response.data.detail
          }
        } else if (error.message) {
          errorMessage = error.message
        }
        ElMessage.error(errorMessage)
      } finally {
        favoritingRoute.value = false
      }
    }
    
    /**
     * 检查时间冲突
     * @param {Object} detail - 路线详情
     * @returns {boolean} - 是否存在时间冲突
     */
    const checkTimeConflict = (detail) => {
      if (!detail.arrival_time || !detail.open_time || !detail.close_time) {
        return false
      }
      
      // 将时间字符串转换为分钟数
      const timeToMinutes = (timeStr) => {
        const [hours, minutes] = timeStr.split(':').map(Number)
        return hours * 60 + minutes
      }
      
      const arrivalMinutes = timeToMinutes(detail.arrival_time)
      const openMinutes = timeToMinutes(detail.open_time)
      const closeMinutes = timeToMinutes(detail.close_time)
      
      // 处理跨天情况（如22:00-02:00）
      if (closeMinutes < openMinutes) {
        // 跨天开放：到达时间应该在开放时间之后或关闭时间之前
        return arrivalMinutes < openMinutes && arrivalMinutes > closeMinutes
      } else {
        // 正常情况：到达时间应该在开放时间范围内
        return arrivalMinutes < openMinutes || arrivalMinutes > closeMinutes
      }
    }
    
    /**
     * 显示的路线上详情（编辑模式下使用可编辑数据，否则使用原始数据）
     */
    const displayRouteDetails = computed(() => {
      if (isEditMode.value && editableRouteDetails.value.length > 0) {
        return editableRouteDetails.value
      }
      return routeResult.value?.optimal_route?.details || []
    })

    /**
     * 检查路线是否存在时间冲突
     * @returns {boolean} - 是否存在时间冲突
     */
    const hasTimeConflicts = computed(() => {
      const details = displayRouteDetails.value
      return details.some(detail => checkTimeConflict(detail))
    })

    /**
     * 切换编辑模式
     */
    const toggleEditMode = () => {
      if (!routeResult.value || !routeResult.value.optimal_route?.details) {
        ElMessage.warning('请先规划路线')
        return
      }

      if (isEditMode.value) {
        // 如果已经在编辑模式，点击后退出编辑模式（不保存）
        ElMessage.info('请点击"完成编辑"保存更改，或点击"取消编辑"放弃更改')
        return
      } else {
        // 进入编辑模式：保存原始路线
        originalRouteDetails.value = [...routeResult.value.optimal_route.details]
        editableRouteDetails.value = [...routeResult.value.optimal_route.details]
        isEditMode.value = true
        ElMessage.info('已进入编辑模式，您可以调整景点顺序或删除景点')
      }
    }

    /**
     * 取消编辑，恢复原始路线
     */
    const cancelEditing = () => {
      editableRouteDetails.value = [...originalRouteDetails.value]
      isEditMode.value = false
      ElMessage.info('已取消编辑，恢复原始路线')
    }

    /**
     * 完成编辑，重新计算路线
     */
    const finishEditing = async () => {
      if (editableRouteDetails.value.length < 2) {
        ElMessage.warning('路线至少需要2个景点')
        return
      }

      try {
        // 提取景点ID列表
        const attractionIds = editableRouteDetails.value.map(detail => 
          detail.attraction_id || detail.attraction?.id
        ).filter(id => id)

        if (attractionIds.length < 2) {
          ElMessage.warning('无法获取景点ID，请重新规划路线')
          isEditMode.value = false
          return
        }

        // 使用新的景点顺序重新规划路线
        loading.value = true
        const routeData = {
          start_attraction_id: attractionIds[0],
          must_visit: attractionIds.slice(1),
          budget: form.budget,
          priority: form.priority,
          transport_mode: form.transport_mode
        }
        
        // 添加时间约束参数（如果存在）
        if (form.start_time) {
          routeData.start_time = form.start_time
        }
        if (form.max_total_time && form.max_total_time > 0) {
          routeData.max_total_time = form.max_total_time
        }

        let result
        if (Array.isArray(routeData.must_visit) && routeData.must_visit.length > 10) {
          planningAsync.value = true
          isPollingCancelled.value = false
          progressMessage.value = '正在重新计算最优路线...'
          const task = await TravelAPI.planRouteAsync(routeData)
          const taskId = task?.task_id
          if (!taskId) {
            ElMessage.error('异步规划任务创建失败')
            loading.value = false
            planningAsync.value = false
            return
          }
          result = await pollPlanStatus(taskId)
          planningAsync.value = false
        } else {
          result = await TravelAPI.planRoute(routeData)
        }
        
        // 更新路线结果
        routeResult.value = result
        if (result.optimal_route && result.optimal_route.details) {
          editableRouteDetails.value = [...result.optimal_route.details]
          originalRouteDetails.value = [...result.optimal_route.details]
          
          // 重新绘制地图
          await drawRouteMap(result.optimal_route.details)
        }

        isEditMode.value = false
        ElMessage.success('路线已更新')
      } catch (error) {
        logger.error('重新计算路线失败:', error)
        ElMessage.error('重新计算路线失败，已恢复原始路线')
        // 恢复原始路线
        editableRouteDetails.value = [...originalRouteDetails.value]
        isEditMode.value = false
      } finally {
        loading.value = false
      }
    }

    /**
     * 轮询规划任务状态，直到成功或失败
     * @param {string} taskId
     */
    const pollPlanStatus = async (taskId) => {
      const maxTries = 120 // 最多轮询2分钟
      const intervalMs = 1000
      let tries = 0
      while (tries < maxTries) {
        if (isPollingCancelled.value) {
          throw new Error('已取消')
        }
        const status = await TravelAPI.getRoutePlanStatus(taskId)
        if (status?.state === 'SUCCESS' && status?.result) {
          progressMessage.value = '规划完成'
          return status.result
        }
        if (status?.state === 'FAILURE') {
          throw new Error(status?.detail || '规划任务失败')
        }
        progressMessage.value = `任务状态：${status?.state || '进行中'}（${tries + 1}/${maxTries}）`
        await new Promise(r => setTimeout(r, intervalMs))
        tries += 1
      }
      throw new Error('规划任务超时')
    }

    /**
     * 取消异步规划
     */
    const cancelAsyncPlanning = () => {
      isPollingCancelled.value = true
      planningAsync.value = false
      ElMessage.info('已取消异步规划')
    }

    /**
     * 上移景点
     */
    const moveAttractionUp = (index) => {
      if (index <= 0) return
      const details = [...editableRouteDetails.value]
      const temp = details[index]
      details[index] = details[index - 1]
      details[index - 1] = temp
      editableRouteDetails.value = details
    }

    /**
     * 下移景点
     */
    const moveAttractionDown = (index) => {
      if (index >= editableRouteDetails.value.length - 1) return
      const details = [...editableRouteDetails.value]
      const temp = details[index]
      details[index] = details[index + 1]
      details[index + 1] = temp
      editableRouteDetails.value = details
    }

    /**
     * 删除景点
     */
    const removeAttraction = (index) => {
      if (editableRouteDetails.value.length <= 1) {
        ElMessage.warning('路线至少需要1个景点')
        return
      }
      
      ElMessageBox.confirm(
        `确定要删除"${editableRouteDetails.value[index].attraction_name}"吗？`,
        '确认删除',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(() => {
        editableRouteDetails.value = editableRouteDetails.value.filter((_, i) => i !== index)
        ElMessage.success('已删除景点')
      }).catch(() => {
        // 用户取消
      })
    }

    onMounted(() => {
      fetchAttractionsImmediate()
      // 如果已登录，加载保存的路线
      if (isAuthenticated.value) {
        loadSavedRoutes()
      }
    })

    onUnmounted(() => {
      if (amapUtil.value) {
        amapUtil.value.destroy()
      }
      // 清理响应式监听器
      if (responsive.cleanup) {
        responsive.cleanup()
      }
    })

    return {
      formRef,
      form,
      rules,
      loading,
      planningAsync,
      progressMessage,
      attractions,
      filteredAttractions,
      fetchAttractionsImmediate,
      routeResult,
      calculateRoute,
      resetForm,
      shareRoute,
      unshareRoute,
      copyShareLink,
      openQRCodeDialog,
      copyShareLinkFromDialog,
      showQRCodeDialog,
      shareQRCodeUrl,
      shareUrl,
      isAuthenticated,
      sharing,
      getCategoryType,
      showCompareDialog,
      savedRoutes,
      selectedRoutesForCompare,
      openCompareDialog,
      loadSavedRoutes,
      compareTableData,
      getCompareCellClass,
      checkSelectable,
      handleRouteSelectionChange,
      compareTableRef,
      toggleRouteFavorite,
      favoritingRoute,
      checkTimeConflict,
      hasTimeConflicts,
      isEditMode,
      editableRouteDetails,
      displayRouteDetails,
      toggleEditMode,
      cancelEditing,
      finishEditing,
      moveAttractionUp,
      moveAttractionDown,
      removeAttraction,
      fitMapView,
      refreshMap,
      toggleMapStyle,
      mapLoading,
      Share,
      CopyDocument,
      MapLocation,
      Setting,
      Search,
      List,
      FullScreen,
      RefreshRight,
      Switch,
      Edit,
      Delete,
      ArrowUp,
      ArrowDown,
      Close,
      Star,
      StarFilled,
      Location,
      Money,
      ScaleToOriginal,
      SuccessFilled,
      View,
      Right,
      CircleCheck,
      Van,
      Guide,
      Bicycle,
      Promotion,
      Clock,
      Timer,
      Picture,
      Loading,
      InfoFilled,
      formatTime,
      getTicketCost,
      getTransportCost,
      getTicketCostPercentage,
      getTransportCostPercentage,
      getAverageCostPerAttraction,
      getAverageDistancePerAttraction,
      getAverageTimePerAttraction,
      isMobile,
      isTablet,
      isDesktop,
      deviceType
      , cancelAsyncPlanning
    }
  }
}
</script>

<style scoped>
.route-plan-container {
  padding: clamp(10px, 2vw, 20px);
  max-width: 1400px;
  margin: 0 auto;
  /* 南昌旅游特色：天空蓝渐变背景 */
  background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 50%, #90CAF9 100%);
  min-height: 100vh;
}

/* 移动端优化 */
@media (max-width: 768px) {
  .route-plan-container {
    padding: 10px;
  }
  
  .page-title {
    font-size: 24px;
  }
  
  .page-subtitle {
    font-size: 14px;
  }
  
  .form-card,
  .result-card {
    margin-bottom: 15px;
  }
  
  /* 表单在移动端使用顶部标签 */
  .form-card :deep(.el-form-item__label) {
    text-align: left;
    margin-bottom: 8px;
  }
  
  /* 按钮在移动端全宽 */
  .form-card :deep(.el-button) {
    width: 100%;
    margin-bottom: 10px;
  }
  
  /* 地图容器在移动端优化 */
  #route-map {
    height: 300px !important;
  }
}

.page-header {
  text-align: center;
  margin-bottom: 40px;
  position: relative;
  padding: 30px 20px;
  background: linear-gradient(135deg, rgba(255,255,255,0.9) 0%, rgba(227,242,253,0.7) 100%);
  border-radius: 16px;
  backdrop-filter: blur(10px);
  box-shadow: 0 4px 20px rgba(200, 16, 46, 0.1);
}

.page-header::before {
  content: '';
  position: absolute;
  top: -2px;
  left: -2px;
  right: -2px;
  bottom: -2px;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 50%, #1E88E5 100%);
  border-radius: 16px;
  z-index: -1;
  opacity: 0.3;
  filter: blur(8px);
}

.page-title {
  font-size: clamp(24px, 4vw, 36px);
  font-weight: 700;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-shadow: 0 2px 4px rgba(200, 16, 46, 0.1);
}

.page-title .el-icon {
  font-size: 1.2em;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.page-subtitle {
  font-size: clamp(14px, 2vw, 18px);
  color: #606266;
  font-weight: 500;
  letter-spacing: 0.5px;
}

.form-card,
.result-card,
.empty-card {
  margin-bottom: 20px;
  border-radius: 16px;
  border: 1px solid rgba(200, 16, 46, 0.12);
  background: linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(227,242,253,0.85) 100%);
  backdrop-filter: blur(12px);
  box-shadow: 0 4px 20px rgba(200, 16, 46, 0.08), 0 1px 3px rgba(0, 0, 0, 0.05);
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
}

.form-card::before,
.result-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #C8102E 0%, #D4AF37 50%, #1E88E5 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.form-card:hover::before,
.result-card:hover::before {
  opacity: 1;
}

.form-card:hover,
.result-card:hover {
  box-shadow: 0 12px 32px rgba(200, 16, 46, 0.15), 0 4px 8px rgba(0, 0, 0, 0.1);
  transform: translateY(-4px);
  border-color: rgba(212, 175, 55, 0.4);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  padding: 4px 0;
}

.card-header > div {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.card-header .el-icon {
  font-size: 1.2em;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.header-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.header-actions .el-button {
  transition: all 0.3s ease;
}

.header-actions .el-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(200, 16, 46, 0.2);
}

.attraction-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
}

.option-name {
  font-weight: 500;
  color: #303133;
  transition: color 0.3s ease;
}

.attraction-select :deep(.el-select-dropdown__item):hover .option-name {
  color: #C8102E;
}

.option-tag {
  margin-left: 8px;
  border-radius: 4px;
  font-weight: 500;
}

.form-tip {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  margin-top: 8px;
  padding: 8px 12px;
  font-size: 12px;
  color: #606266;
  line-height: 1.6;
  background: rgba(200, 16, 46, 0.05);
  border-radius: 6px;
  border-left: 3px solid rgba(200, 16, 46, 0.3);
  transition: all 0.3s ease;
}

.form-tip:hover {
  background: rgba(200, 16, 46, 0.08);
  border-left-color: rgba(200, 16, 46, 0.5);
}

.form-tip .el-icon {
  color: #C8102E;
  font-size: 14px;
  margin-top: 2px;
  flex-shrink: 0;
}

.budget-input-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
  position: relative;
}

.budget-icon {
  font-size: 20px;
  color: #606266;
  flex-shrink: 0;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.budget-input {
  flex: 1;
}

.time-constraint-wrapper {
  width: 100%;
}

.time-input-group {
  display: flex;
  align-items: center;
  gap: 8px;
  position: relative;
}

.time-icon {
  font-size: 18px;
  color: #606266;
  flex-shrink: 0;
}

.time-picker-input,
.time-number-input {
  flex: 1;
}

.time-constraint-info {
  font-size: 13px;
  line-height: 1.6;
}

.time-constraint-info .el-icon {
  margin-right: 4px;
  vertical-align: middle;
}

.compare-results {
  margin-top: 20px;
}

.best-value {
  color: #67c23a;
  font-weight: 600;
}

.result-summary {
  margin-bottom: 30px;
  padding: 24px;
  background: linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(227,242,253,0.9) 100%);
  border-radius: 16px;
  border: 1px solid rgba(200, 16, 46, 0.12);
  backdrop-filter: blur(12px);
  box-shadow: 0 4px 20px rgba(200, 16, 46, 0.08);
}

.summary-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 2px solid rgba(200, 16, 46, 0.1);
}

.summary-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.summary-grid {
  margin-bottom: 24px;
}

.summary-item {
  display: flex;
  align-items: center;
  padding: 24px 20px;
  background: linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(227,242,253,0.85) 100%);
  border-radius: 12px;
  border: 1px solid rgba(200, 16, 46, 0.1);
  backdrop-filter: blur(10px);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  overflow: hidden;
  height: 100%;
  min-height: 120px;
}

.summary-item::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 4px;
  height: 100%;
  background: linear-gradient(180deg, #C8102E 0%, #D4AF37 100%);
  transition: width 0.3s ease;
}

.summary-item:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(200, 16, 46, 0.15);
  border-color: rgba(212, 175, 55, 0.4);
}

.summary-item:hover::before {
  width: 6px;
}

.summary-item:nth-child(1)::before {
  background: linear-gradient(180deg, #C8102E 0%, #D4AF37 100%);
}

.summary-item:nth-child(2)::before {
  background: linear-gradient(180deg, #1E88E5 0%, #42A5F5 100%);
}

.summary-item:nth-child(3)::before {
  background: linear-gradient(180deg, #4CAF50 0%, #66BB6A 100%);
}

.summary-item:nth-child(4)::before {
  background: linear-gradient(180deg, #D4AF37 0%, #F4D03F 100%);
}

.summary-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 20px;
  font-size: 32px;
  flex-shrink: 0;
  position: relative;
  overflow: hidden;
}

.summary-icon::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  padding: 2px;
  background: linear-gradient(135deg, #C8102E, #D4AF37);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0.6;
}

.summary-icon.cost {
  background: linear-gradient(135deg, rgba(200, 16, 46, 0.1) 0%, rgba(212, 175, 55, 0.1) 100%);
  color: #C8102E;
}

.summary-icon.cost::before {
  background: linear-gradient(135deg, #C8102E, #D4AF37);
}

.summary-icon.distance {
  background: linear-gradient(135deg, rgba(30, 136, 229, 0.1) 0%, rgba(66, 165, 245, 0.1) 100%);
  color: #1E88E5;
}

.summary-icon.distance::before {
  background: linear-gradient(135deg, #1E88E5, #42A5F5);
}

.summary-icon.time {
  background: linear-gradient(135deg, rgba(76, 175, 80, 0.1) 0%, rgba(102, 187, 106, 0.1) 100%);
  color: #4CAF50;
}

.summary-icon.time::before {
  background: linear-gradient(135deg, #4CAF50, #66BB6A);
}

.summary-icon.count {
  background: linear-gradient(135deg, rgba(212, 175, 55, 0.1) 0%, rgba(244, 208, 63, 0.1) 100%);
  color: #D4AF37;
}

.summary-icon.count::before {
  background: linear-gradient(135deg, #D4AF37, #F4D03F);
}

.summary-icon-wrapper {
  margin-right: 16px;
  flex-shrink: 0;
}

.summary-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.summary-label {
  font-size: 13px;
  color: #909399;
  font-weight: 500;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

.summary-value {
  font-size: clamp(22px, 3vw, 28px);
  font-weight: 700;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  line-height: 1.2;
}

.summary-unit {
  font-size: 12px;
  color: #909399;
  font-weight: 400;
}

/* 路线统计图表 */
.route-stats-chart {
  margin-top: 24px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 12px;
  border: 1px solid rgba(200, 16, 46, 0.08);
}

.chart-header {
  margin-bottom: 20px;
}

.chart-header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  display: flex;
  align-items: center;
  gap: 8px;
}

.stats-bars {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 20px;
}

.stat-bar-item {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.bar-label {
  font-size: 13px;
  color: #606266;
  font-weight: 500;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.bar-container {
  height: 32px;
  background: rgba(200, 16, 46, 0.08);
  border-radius: 16px;
  overflow: hidden;
  position: relative;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
}

.bar-fill {
  height: 100%;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 12px;
  transition: width 0.6s ease;
  position: relative;
  overflow: hidden;
}

.bar-fill.ticket {
  background: linear-gradient(90deg, #C8102E 0%, #E53935 100%);
  box-shadow: 0 2px 8px rgba(200, 16, 46, 0.3);
}

.bar-fill.transport {
  background: linear-gradient(90deg, #1E88E5 0%, #42A5F5 100%);
  box-shadow: 0 2px 8px rgba(30, 136, 229, 0.3);
}

.bar-value {
  color: white;
  font-size: 12px;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  white-space: nowrap;
}

.route-efficiency {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(200, 16, 46, 0.1);
}

.efficiency-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  background: rgba(255, 255, 255, 0.8);
  border-radius: 8px;
  border: 1px solid rgba(200, 16, 46, 0.1);
  font-size: 13px;
  color: #606266;
  flex: 1;
  min-width: calc(33.333% - 12px);
}

.efficiency-item .el-icon {
  color: #C8102E;
  font-size: 16px;
}

.route-details {
  margin-top: 30px;
}

.section-header {
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 2px solid rgba(200, 16, 46, 0.1);
}

.section-title-wrapper {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.section-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.route-badge {
  display: flex;
  gap: 8px;
  align-items: center;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20px;
  gap: 20px;
}

.section-title {
  font-size: 22px;
  font-weight: 700;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  transition: all 0.3s ease;
}

.section-title .el-icon {
  font-size: 1.2em;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.edit-mode-tips {
  flex: 1;
  max-width: 500px;
}

.edit-tips-content p {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: #606266;
}

.edit-tips-actions {
  display: flex;
  gap: 10px;
  margin-top: 8px;
}

.edit-tips-actions .el-button {
  flex: 1;
  transition: all 0.3s ease;
}

.edit-tips-actions .el-button[type="success"] {
  background: linear-gradient(135deg, #4CAF50 0%, #66BB6A 100%);
  border: none;
}

.edit-tips-actions .el-button[type="success"]:hover {
  background: linear-gradient(135deg, #66BB6A 0%, #4CAF50 100%);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
}

.edit-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.edit-actions .el-button {
  transition: all 0.3s ease;
}

.edit-actions .el-button:hover {
  transform: scale(1.1);
}

.edit-actions .el-button[type="primary"]:hover {
  color: #1E88E5;
  background: rgba(30, 136, 229, 0.1);
}

.edit-actions .el-button[type="danger"]:hover {
  color: #C8102E;
  background: rgba(200, 16, 46, 0.1);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.detail-card {
  margin-bottom: 16px;
  border-radius: 16px;
  border: 1px solid rgba(200, 16, 46, 0.1);
  background: linear-gradient(135deg, rgba(255,255,255,0.98) 0%, rgba(227,242,253,0.85) 100%);
  backdrop-filter: blur(12px);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
  position: relative;
  box-shadow: 0 2px 12px rgba(200, 16, 46, 0.08);
}

.detail-card.is-start {
  border: 2px solid rgba(103, 194, 58, 0.3);
  background: linear-gradient(135deg, rgba(103, 194, 58, 0.05) 0%, rgba(255,255,255,0.95) 100%);
}

.detail-card.is-start::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: linear-gradient(180deg, #67c23a 0%, #85ce61 100%);
}

.detail-card:not(.is-start)::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, #C8102E 0%, #D4AF37 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.detail-card:hover {
  box-shadow: 0 4px 16px rgba(200, 16, 46, 0.12);
  transform: translateX(4px);
  border-color: rgba(212, 175, 55, 0.3);
}

.detail-card:not(.is-start):hover::before {
  opacity: 1;
}

.detail-card.editable {
  border: 2px dashed rgba(200, 16, 46, 0.4);
  background: linear-gradient(135deg, rgba(200, 16, 46, 0.05) 0%, rgba(212, 175, 55, 0.05) 100%);
  animation: pulse-border 2s ease-in-out infinite;
}

@keyframes pulse-border {
  0%, 100% {
    border-color: rgba(200, 16, 46, 0.4);
  }
  50% {
    border-color: rgba(200, 16, 46, 0.6);
  }
}

.detail-card.editable:hover {
  border-color: rgba(200, 16, 46, 0.6);
  background: linear-gradient(135deg, rgba(200, 16, 46, 0.08) 0%, rgba(212, 175, 55, 0.08) 100%);
  transform: translateX(0);
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 2px solid rgba(200, 16, 46, 0.1);
  gap: 16px;
}

.attraction-header-left {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
}

.attraction-order {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 12px;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  color: white;
  flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(200, 16, 46, 0.3);
  transition: all 0.3s ease;
}

.detail-card.is-start .attraction-order {
  background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
  box-shadow: 0 4px 12px rgba(103, 194, 58, 0.3);
}

.detail-card:hover .attraction-order {
  transform: scale(1.05);
  box-shadow: 0 6px 16px rgba(200, 16, 46, 0.4);
}

.order-number {
  font-size: 20px;
  font-weight: 700;
  line-height: 1;
}

.order-label {
  font-size: 10px;
  font-weight: 500;
  opacity: 0.9;
  margin-top: 2px;
}

.attraction-name {
  font-size: 18px;
  font-weight: 600;
  background: linear-gradient(135deg, #303133 0%, #606266 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin: 0;
  transition: all 0.3s ease;
  flex: 1;
}

.detail-card:hover .attraction-name {
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  transform: translateX(2px);
}

.price-text {
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  font-weight: 700;
  font-size: 18px;
}

.route-info {
  margin-top: 15px;
}

.transport-info {
  display: flex;
  align-items: center;
  gap: 5px;
  color: #67c23a;
  font-weight: 500;
  margin-bottom: 10px;
}

.map-container {
  margin-top: 30px;
  position: relative;
}

.map-container::before {
  content: '';
  position: absolute;
  top: -2px;
  left: -2px;
  right: -2px;
  bottom: -2px;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 50%, #1E88E5 100%);
  border-radius: 12px;
  z-index: -1;
  opacity: 0.25;
  filter: blur(10px);
  transition: opacity 0.3s ease;
}

.map-container:hover::before {
  opacity: 0.35;
}

.map-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.map-controls {
  display: flex;
  gap: 8px;
}

.map-control-btn {
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(200, 16, 46, 0.2);
  color: #C8102E;
  transition: all 0.3s ease;
}

.map-control-btn:hover {
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  color: white;
  border-color: transparent;
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(200, 16, 46, 0.3);
}

.route-map {
  width: 100%;
  height: 500px;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(200, 16, 46, 0.15), 0 2px 8px rgba(0, 0, 0, 0.1);
  border: 2px solid rgba(200, 16, 46, 0.15);
  transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
}

.route-map::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #C8102E 0%, #D4AF37 50%, #1E88E5 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.route-map:hover::after {
  opacity: 1;
}

.route-map:hover {
  box-shadow: 0 12px 32px rgba(200, 16, 46, 0.2), 0 4px 12px rgba(0, 0, 0, 0.15);
  border-color: rgba(212, 175, 55, 0.4);
  transform: translateY(-2px);
}

.map-legend {
  display: flex;
  gap: 20px;
  margin-top: 15px;
  padding: 12px 20px;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(10px);
  border-radius: 8px;
  border: 1px solid rgba(200, 16, 46, 0.15);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: #606266;
}

.legend-marker {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-block;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.legend-marker.start {
  background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
  border: 2px solid white;
}

.legend-marker.waypoint {
  background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
  border: 2px solid white;
}

.legend-marker.route {
  width: 24px;
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(90deg, #C8102E 0%, #D4AF37 50%, #1E88E5 100%);
}

.empty-card {
  min-height: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px;
}

.empty-icon {
  font-size: 100px;
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 50%, #1E88E5 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin-bottom: 24px;
  animation: float 3s ease-in-out infinite;
}

@keyframes float {
  0%, 100% {
    transform: translateY(0px);
  }
  50% {
    transform: translateY(-10px);
  }
}

.plan-button {
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  border: none;
  font-weight: 600;
  letter-spacing: 1px;
  box-shadow: 0 4px 12px rgba(200, 16, 46, 0.3);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.plan-button::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
  transition: left 0.5s ease;
}

.plan-button:hover::before {
  left: 100%;
}

.plan-button:hover {
  background: linear-gradient(135deg, #D4AF37 0%, #C8102E 100%);
  box-shadow: 0 6px 20px rgba(200, 16, 46, 0.4);
  transform: translateY(-2px);
}

.plan-button:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(200, 16, 46, 0.3);
}

.reset-button {
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(200, 16, 46, 0.2);
  color: #606266;
  transition: all 0.3s ease;
  backdrop-filter: blur(10px);
}

.reset-button:hover {
  background: rgba(200, 16, 46, 0.08);
  border-color: rgba(200, 16, 46, 0.4);
  color: #C8102E;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(200, 16, 46, 0.2);
}

.priority-group {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.priority-button {
  flex: 1;
  min-width: 120px;
  transition: all 0.3s ease;
}

.priority-button :deep(.el-radio-button__inner) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 12px 16px;
  border-radius: 8px;
  border-color: rgba(200, 16, 46, 0.2);
  transition: all 0.3s ease;
}

.priority-button :deep(.el-radio-button__inner):hover {
  border-color: rgba(200, 16, 46, 0.4);
  color: #C8102E;
  background: rgba(200, 16, 46, 0.05);
}

.priority-button :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
  background: linear-gradient(135deg, #C8102E 0%, #D4AF37 100%);
  border-color: transparent;
  color: white;
  box-shadow: 0 2px 8px rgba(200, 16, 46, 0.3);
}

.priority-button :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner):hover {
  background: linear-gradient(135deg, #D4AF37 0%, #C8102E 100%);
  box-shadow: 0 4px 12px rgba(200, 16, 46, 0.4);
}

.transport-group {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.transport-button {
  flex: 1;
  min-width: 100px;
  transition: all 0.3s ease;
}

.transport-button :deep(.el-radio-button__inner) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 12px 16px;
  border-radius: 8px;
  border-color: rgba(200, 16, 46, 0.2);
  transition: all 0.3s ease;
}

.transport-button :deep(.el-radio-button__inner):hover {
  border-color: rgba(200, 16, 46, 0.4);
  color: #C8102E;
  background: rgba(200, 16, 46, 0.05);
}

.transport-button :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
  background: linear-gradient(135deg, #1E88E5 0%, #42A5F5 100%);
  border-color: transparent;
  color: white;
  box-shadow: 0 2px 8px rgba(30, 136, 229, 0.3);
}

.transport-button :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner):hover {
  background: linear-gradient(135deg, #42A5F5 0%, #1E88E5 100%);
  box-shadow: 0 4px 12px rgba(30, 136, 229, 0.4);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .route-plan-container {
    padding: 15px;
  }

  .summary-item {
    padding: 20px;
  }
}

/* 平板设备 (768px - 991px) */
@media (min-width: 768px) and (max-width: 991px) {
  .route-plan-container {
    padding: 15px;
  }

  .form-card {
    margin-bottom: 20px;
  }

  .route-map {
    height: 400px;
  }

  .summary-item {
    padding: 18px;
  }
}

/* 移动设备 (最大768px) */
@media (max-width: 768px) {
  .route-plan-container {
    padding: 10px;
  }

  .page-header {
    padding: 15px 10px;
    margin-bottom: 15px;
  }

  .page-title {
    font-size: clamp(20px, 5vw, 28px);
    flex-direction: column;
    gap: 8px;
    text-align: center;
  }

  .page-subtitle {
    font-size: clamp(12px, 3vw, 14px);
    text-align: center;
  }

  .form-card {
    margin-bottom: 15px;
  }

  .form-card :deep(.el-card__header) {
    padding: 15px;
  }

  .form-card :deep(.el-card__body) {
    padding: 15px;
  }

  .form-card :deep(.el-form-item) {
    margin-bottom: 16px;
  }

  .form-card :deep(.el-form-item__label) {
    margin-bottom: 8px;
    font-size: 14px;
  }

  .form-card :deep(.el-radio-group) {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  .form-card :deep(.el-radio-button) {
    flex: 1;
    min-width: calc(50% - 4px);
  }

  .form-card :deep(.el-radio-button__inner) {
    padding: 10px 15px;
    font-size: 13px;
  }

  .plan-button {
    width: 100%;
    padding: 14px;
    font-size: 16px;
  }

  .summary-item {
    flex-direction: column;
    text-align: center;
    padding: 16px;
  }

  .summary-icon {
    margin-right: 0;
    margin-bottom: 12px;
  }

  .summary-value {
    font-size: clamp(20px, 5vw, 28px);
  }

  .summary-label {
    font-size: 13px;
  }

  .route-map {
    height: 300px;
  }

  .map-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .map-controls {
    width: 100%;
    justify-content: flex-end;
  }

  .map-legend {
    flex-wrap: wrap;
    gap: 12px;
    padding: 10px 15px;
  }

  .detail-card {
    margin-bottom: 10px;
  }

  .detail-card :deep(.el-card__body) {
    padding: 15px;
  }

  .edit-actions {
    flex-wrap: wrap;
    gap: 6px;
  }

  .edit-actions .el-button {
    flex: 1;
    min-width: calc(50% - 3px);
  }
}

/* 小屏移动设备 (最大480px) */
@media (max-width: 480px) {
  .route-plan-container {
    padding: 8px;
  }

  .page-header {
    padding: 12px 8px;
  }

  .page-title {
    font-size: 20px;
  }

  .page-subtitle {
    font-size: 12px;
  }

  .form-card :deep(.el-card__header),
  .form-card :deep(.el-card__body) {
    padding: 12px;
  }

  .summary-item {
    padding: 12px;
  }

  .summary-value {
    font-size: 20px;
  }

  .route-map {
    height: 250px;
  }

  .map-control-btn {
    padding: 8px;
  }

  .detail-card :deep(.el-card__body) {
    padding: 12px;
  }

  .card-actions {
    flex-direction: column;
    gap: 8px;
  }

  .card-actions .el-button {
    width: 100%;
  }
}

/* 横屏移动设备 */
@media (max-width: 768px) and (orientation: landscape) {
  .route-map {
    height: 250px;
  }
}
</style>
